﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Company.Core.Helpers;
using Company.Core.Logger;
using Company.Shell.Interfaces;
using Company.Shell.Models;
using Company.Shell.Services;
using LiveCharts;
using LiveCharts.Defaults;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Windows.Input;

namespace Company.Shell.ViewModels
{
    internal class HistoryViewModel : ObservableObject
    {
        private ObservableCollection<FileInfo> files = new();
        /// <summary>
        /// 所有曲线文件
        /// </summary>
        public ObservableCollection<FileInfo> Files 
        { 
            get { return files; }
            set { SetProperty(ref files, value); }
        }
        private FileInfo? file;
        /// <summary>
        /// 当前曲线文件
        /// </summary>
        public FileInfo? FileInfo
        {
            get { return file; }
            set { SetProperty(ref file, value); }
        }

        #region 12个数字量的曲线

        private ChartValues<ObservablePoint> line0 = new();
        public ChartValues<ObservablePoint> Line0
        {
            get => line0;
            set => SetProperty(ref line0, value);
        }

        private ChartValues<ObservablePoint> line1 = new();
        public ChartValues<ObservablePoint> Line1
        {
            get => line1;
            set => SetProperty(ref line1, value);
        }
        private ChartValues<ObservablePoint> line2 = new();
        public ChartValues<ObservablePoint> Line2
        {
            get => line2;
            set => SetProperty(ref line2, value);
        }
        private ChartValues<ObservablePoint> line3 = new();
        public ChartValues<ObservablePoint> Line3
        {
            get => line3;
            set => SetProperty(ref line3, value);
        }
        private ChartValues<ObservablePoint> line4 = new();
        public ChartValues<ObservablePoint> Line4
        {
            get => line4;
            set => SetProperty(ref line4, value);
        }
        private ChartValues<ObservablePoint> line5 = new();
        public ChartValues<ObservablePoint> Line5
        {
            get => line5;
            set => SetProperty(ref line5, value);
        }
        private ChartValues<ObservablePoint> line6 = new();
        public ChartValues<ObservablePoint> Line6
        {
            get => line6;
            set => SetProperty(ref line6, value);
        }
        private ChartValues<ObservablePoint> line7 = new();
        public ChartValues<ObservablePoint> Line7
        {
            get => line7;
            set => SetProperty(ref line7, value);
        }
        private ChartValues<ObservablePoint> line8 = new();
        public ChartValues<ObservablePoint> Line8
        {
            get => line8;
            set => SetProperty(ref line8, value);
        }
        private ChartValues<ObservablePoint> line9 = new();
        public ChartValues<ObservablePoint> Line9
        {
            get => line9;
            set => SetProperty(ref line9, value);
        }
        private ChartValues<ObservablePoint> line10 = new();
        public ChartValues<ObservablePoint> Line10
        {
            get => line10;
            set => SetProperty(ref line10, value);
        }
        private ChartValues<ObservablePoint> line11 = new();
        public ChartValues<ObservablePoint> Line11
        {
            get => line11;
            set => SetProperty(ref line11, value);
        }
        #endregion
        public ICommand? LoadedCommand { get; }
        public ICommand? SelectFileCommand { get;}
        public ICommand? SelectRoomCommand { get; }
        public IRoomManager RoomManager { get; set; }
        public IProgramManager ProgramManager { get; }

        public HistoryViewModel(IRoomManager roomManager,
            IProgramManager programManager)
        {
            ProgramManager = programManager;
            RoomManager = roomManager;
            SelectFileCommand = new AsyncRelayCommand(OnSelectFileCommand);
            LoadedCommand = new AsyncRelayCommand(OnLoadedCommand);
            SelectRoomCommand = new AsyncRelayCommand(OnSelectRoomCommand);
        }

        //切换房间时，重新加载文件列表
        private async Task OnSelectRoomCommand()
        {
            if (RoomManager.Room != null)
            {
                Files = await InitializeFiles(RoomManager.Room);
            }
        }

        private async Task OnLoadedCommand()
        {
            if (RoomManager.Room != null)
            {
                Files = await InitializeFiles(RoomManager.Room);
            }

        }

        /// <summary>
        /// 加载当前房间的历史文件名
        /// </summary>
        /// <param name="room"></param>
        /// <returns></returns>
        private async Task<ObservableCollection<FileInfo>> InitializeFiles(RoomEntity room)
        {
            return await Task.Run(() =>
            {
                ObservableCollection<FileInfo> result = new ObservableCollection<FileInfo>();
                var folder = CurveHelper.GetCurveFolder(DateTime.Now.Year);
                DirectoryInfo dir = new DirectoryInfo(folder);
                if (dir.Exists)
                {
                    var files = dir.GetFiles().Where(t => t.Extension == ".csv").ToList();
                    foreach (var file in files)
                    {
                        var tempArray = file.Name.Split('-');
                        if (tempArray.Length > 0 && tempArray[0] == $"room{room.Id}")
                        {
                            result.Add(file);
                        }
                    }
                }

                return result;
            });
        }

        private async Task OnSelectFileCommand()
        {
            await InitializeCurve(FileInfo);
        }

        /// <summary>
        /// 加载曲线数据
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private async Task InitializeCurve(FileInfo file)
        {
            if (file == null) return;
            if (!File.Exists(file.FullName))
                return;
            await Task.Run(() => 
            {
                System.Windows.Application.Current.Dispatcher.Invoke(() =>
                {
                    Line0.Clear();
                    Line1.Clear();
                    Line2.Clear();
                    Line3.Clear();
                    Line4.Clear();
                    Line5.Clear();
                    Line6.Clear();
                    Line7.Clear();
                    Line8.Clear();
                    Line9.Clear();
                    Line10.Clear();
                    Line11.Clear();
                });

                //读csv文件
                List<string> rows = File.ReadAllLines(file.FullName,Encoding.Default).ToList();
                if(rows==null || rows.Count==0) return;
                rows.RemoveAt(0);

                try
                {
                    foreach (var row in rows)
                    {
                        string[] columns = row.Split(',');
                        if (columns == null || columns.Length == 0) continue;
                        var success = double.TryParse(columns[1], out double x);
                        if (!success) continue;
                        var point0 = new ObservablePoint(x, double.Parse(columns[2]));
                        var point1 = new ObservablePoint(x, double.Parse(columns[3]));
                        var point2 = new ObservablePoint(x, double.Parse(columns[4]));
                        var point3 = new ObservablePoint(x, double.Parse(columns[5]));
                        var point4 = new ObservablePoint(x, double.Parse(columns[6]));
                        var point5 = new ObservablePoint(x, double.Parse(columns[7]));
                        var point6 = new ObservablePoint(x, double.Parse(columns[8]));
                        var point7 = new ObservablePoint(x, double.Parse(columns[9]));
                        var point8 = new ObservablePoint(x, double.Parse(columns[10]));
                        var point9 = new ObservablePoint(x, double.Parse(columns[11]));
                        var point10 = new ObservablePoint(x, double.Parse(columns[12]));
                        var point11 = new ObservablePoint(x, double.Parse(columns[13]));
                        var point12 = new ObservablePoint(x, double.Parse(columns[14]));
                        var point13 = new ObservablePoint(x, double.Parse(columns[15]));
                        System.Windows.Application.Current.Dispatcher.Invoke(() =>
                        {
                            Line0.Add(point0);
                            Line1.Add(point1);
                            Line2.Add(point2);
                            Line3.Add(point3);
                            Line4.Add(point4);
                            Line5.Add(point5);
                            Line6.Add(point6);
                            Line7.Add(point7);
                            Line8.Add(point8);
                            Line9.Add(point9);
                            Line10.Add(point10);
                            Line11.Add(point11);
                        });
                    }
                }
                catch (Exception ex)
                {
                    Logs.Error(ex);
                }
            });
        }
    }
}
